package com.pinfly.common.config;

import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.io.StringWriter;
import java.io.Writer;
import java.util.Properties;

import org.apache.log4j.Logger;

import com.pinfly.common.util.StringUtil;

public class BaseConfigUtil
{
    private static final Logger LOGGER = Logger.getLogger (BaseConfigUtil.class);

    /**
     * Returns the specified property as a boolean.
     * 
     * @param prop
     * @param name
     * @param def
     * @return boolean
     */
    public static boolean getBooleanProperty (Properties prop, String name, boolean def)
    {
        if (prop == null)
        {
            throw new IllegalArgumentException ("prop cannot be null");
        }

        if (StringUtil.isNullOrBlank (name))
        {
            throw new IllegalArgumentException ("name cannot be null or empty string");
        }

        String val = prop.getProperty (name);
        if (val == null || ((!"true".equalsIgnoreCase (val)) && (!"false".equalsIgnoreCase (val))))
        {
            LOGGER.warn ("Unable to parse " + name + ": " + val + " defaulting to " + def);
            return def;
        }

        return Boolean.valueOf (val).booleanValue ();
    }

    /**
     * Returns the specified property as an int
     * 
     * @param prop
     * @param name
     * @param def
     * @return property as int
     */
    public static int getIntProperty (Properties prop, String name, int def)
    {
        if (prop == null)
        {
            throw new IllegalArgumentException ("prop cannot be null");
        }

        if (StringUtil.isNullOrBlank (name))
        {
            throw new IllegalArgumentException ("name cannot be null or empty string");
        }

        String val = prop.getProperty (name);
        try
        {
            return Integer.parseInt (val);
        }
        catch (NumberFormatException nfe)
        {
            LOGGER.warn ("Unable to parse " + name + ": " + val + " defaulting to " + def, nfe);
            return def;
        }
    }

    /**
     * Returns the specified property as a long
     * 
     * @param prop
     * @param name
     * @param def
     * @return property as long
     */
    public static long getLongProperty (Properties prop, String name, long def)
    {
        if (prop == null)
        {
            throw new IllegalArgumentException ("prop cannot be null");
        }

        if (StringUtil.isNullOrBlank (name))
        {
            throw new IllegalArgumentException ("name cannot be null or empty string");
        }

        String val = prop.getProperty (name);
        try
        {
            return Long.parseLong (val);
        }
        catch (NumberFormatException nfe)
        {
            LOGGER.warn ("Unable to parse " + name + ": " + val + " defaulting to " + def, nfe);
            return def;
        }
    }

    public static String getPfyPropertiesDir ()
    {
        String propDir = System.getProperty (BaseConfigConstants.PINFLY_PROPS_DIR);
        if (StringUtil.isNullOrBlank (propDir))
        {
            String cfxHome = System.getenv (BaseConfigConstants.PINFLY_HOME_ENV);
            if (!StringUtil.isNullOrBlank (cfxHome))
            {
                return cfxHome + File.separator + BaseConfigConstants.COMMON + File.separator
                       + BaseConfigConstants.PROPERTIES;
            }
        }
        // Just return the propDir
        return propDir;
    }

    public static String getCxxCommonDir ()
    {
        String propDir = System.getProperty (BaseConfigConstants.COMMON_PROPERTY_DIR);
        if (StringUtil.isNullOrBlank (propDir))
        {
            String cfxHome = System.getenv (BaseConfigConstants.PINFLY_HOME_ENV);
            if (!StringUtil.isNullOrBlank (cfxHome))
            {
                return cfxHome + File.separator + BaseConfigConstants.COMMON;
            }
        }
        // Just return the propDir
        return propDir;
    }

    public static String convertStreamToString (InputStream is) throws IOException
    {
        /*
         * To convert the InputStream to String we use the Reader.read(char[]
         * buffer) method. We iterate until the Reader return -1 which means
         * there's no more data to read. We use the StringWriter class to
         * produce the string.
         */
        if (is != null)
        {
            Writer writer = new StringWriter ();
            char[] buffer = new char[1024];
            try
            {
                Reader reader = new BufferedReader (new InputStreamReader (is, "UTF-8"));
                int n;
                while ((n = reader.read (buffer)) != -1)
                {
                    writer.write (buffer, 0, n);
                }
            }
            finally
            {
                is.close ();
            }
            return writer.toString ();
        }
        else
        {
            return "";
        }
    }
}
